Skip to main content

Next.js 면접 준비

작성일 : 2025.01.19

1. "Next.js가 무엇이며, React와의 주요 차이점은 무엇인가요?"​

Next.js는 React를 기반으로 한 풀스택 웹 프레임워크로, React의 기능을 확장하여 더욱 강력한 웹 애플리케이션 개발 환경을 제공합니다. React가 UI 라이브러리로서의 역할에 중점을 둔다면, Next.js는 이를 포함하면서도 더 포괄적인 개발 솔루션을 제공합니다.

가장 두드러진 차이점은 Next.js가 서버 사이드 렌더링(SSR)과 정적 사이트 생성(SSG)을 기본적으로 지원한다는 점입니다. 이를 통해 초기 페이지 로딩 속도를 개선하고 검색 엔진 최적화(SEO)를 강화할 수 있습니다. 또한, Next.js는 파일 시스템을 기반으로 한 직관적인 라우팅 시스템을 제공하여, 개발자가 복잡한 라우팅 설정 없이도 페이지를 쉽게 구성할 수 있게 해줍니다.

Next.js의 또 다른 강점은 자동 코드 스플리팅 기능입니다. 이는 각 페이지에 필요한 JavaScript 코드만을 로드하여 초기 번들 크기를 줄이고 애플리케이션의 성능을 최적화합니다. 추가로, API 라우트를 내장하고 있어 별도의 백엔드 서버 없이도 API 엔드포인트를 쉽게 생성하고 관리할 수 있습니다.

마지막으로, Next.js는 이미지, 폰트, 스크립트와 같은 정적 자원들을 자동으로 최적화하는 기능을 제공합니다. 이미지 컴포넌트는 자동 크기 조정, 포맷 변환, lazy loading을 지원하며, 폰트와 스크립트도 최적화된 로딩 전략을 통해 더 나은 성능을 제공합니다. 이러한 기능들은 개발자가 성능 최적화에 들이는 시간과 노력을 크게 줄여줍니다.

2. "Next.js의 렌더링 방식들을 설명해주세요."​

Next.js는 웹 애플리케이션의 다양한 요구사항을 충족시키기 위해 네 가지의 핵심적인 렌더링 방식을 제공합니다.

먼저, Server Side Rendering(SSR)은 사용자의 요청이 있을 때마다 서버에서 페이지를 동적으로 생성하는 방식입니다. getServerSideProps 함수를 통해 구현되며, 실시간 데이터가 필요하거나 사용자별 맞춤 콘텐츠를 제공해야 하는 페이지에 적합합니다. 매 요청마다 최신 데이터로 페이지를 생성할 수 있다는 장점이 있지만, 서버 부하가 상대적으로 크다는 특징이 있습니다.

Static Site Generation(SSG)은 빌드 시점에 페이지를 미리 생성하여 제공하는 방식입니다. getStaticProps를 사용하여 구현하며, 모든 사용자에게 동일한 콘텐츠를 제공하는 블로그 포스트나 제품 소개 페이지와 같이 자주 변경되지 않는 콘텐츠에 이상적입니다. 한번 생성된 페이지를 재사용할 수 있어 매우 빠른 응답 속도를 제공합니다.

Incremental Static Regeneration(ISR)은 SSG의 확장된 형태로, 정적 페이지를 주기적으로 재생성할 수 있게 해줍니다. getStaticProps 함수에 revalidate 옵션을 설정하여 구현하며, 데이터의 실시간성과 정적 페이지의 성능 이점을 모두 얻을 수 있습니다. 예를 들어, 주기적으로 업데이트되는 뉴스 기사나 상품 정보 페이지에 적합합니다.

마지막으로, Client Side Rendering(CSR)은 브라우저에서 JavaScript를 실행하여 페이지를 렌더링하는 전통적인 React의 방식입니다. useEffect 훅이나 SWR, React Query와 같은 데이터 페칭 라이브러리를 사용하여 구현합니다. 사용자 대시보드나 실시간 채팅과 같이 빈번한 데이터 업데이트가 필요한 동적인 기능에 적합합니다. 초기 로딩 시간이 다소 길 수 있지만, 이후의 상호작용은 매우 빠르게 이루어진다는 특징이 있습니다.

이러한 다양한 렌더링 방식을 제공함으로써, Next.js는 개발자가 각 페이지의 특성과 요구사항에 맞는 최적의 렌더링 전략을 선택할 수 있게 해줍니다.

3. "Next.js의 파일 기반 라우팅에 대해 설명해주세요."​

Next.js는 직관적이고 편리한 파일 시스템 기반의 라우팅 시스템을 제공합니다. 이는 pages 디렉토리의 파일 구조를 웹 애플리케이션의 URL 구조로 자동 변환하는 방식으로 작동합니다.

가장 기본적인 형태로, 루트 경로('/')는 pages 디렉토리의 index.js 파일에 의해 처리됩니다. 예를 들어 홈페이지의 경우 pages/index.js 파일이 담당하게 됩니다. 일반적인 정적 경로는 파일 이름을 그대로 URL 경로로 사용합니다. pages/about.js 파일은 '/about' URL로 자동 매핑되며, pages/contact.js는 '/contact' 경로로 연결됩니다.

동적 라우팅이 필요한 경우, 대괄호([])를 사용하여 처리할 수 있습니다. 예를 들어, pages/posts/[id].js 파일은 '/posts/1', '/posts/2' 등과 같은 동적 URL을 처리할 수 있으며, 컴포넌트 내에서 useRouter 훅을 통해 id 값을 쉽게 접근할 수 있습니다. 이는 블로그 포스트나 제품 상세 페이지와 같이 동적 콘텐츠를 표시해야 하는 경우에 유용합니다.

더 복잡한 동적 라우팅이 필요한 경우, Catch-all 라우팅을 사용할 수 있습니다. pages/posts/[...slug].js와 같은 형식으로 파일을 생성하면, '/posts/a/b/c'와 같은 여러 단계의 경로를 하나의 컴포넌트에서 처리할 수 있습니다. 이는 복잡한 URL 구조나 다단계 카테고리 시스템을 구현할 때 특히 유용합니다.

이러한 파일 기반 라우팅 시스템은 별도의 라우팅 설정 파일이 필요 없어 프로젝트 구조를 더욱 명확하게 만들어주며, 개발자가 직관적으로 라우팅 구조를 파악하고 관리할 수 있게 해줍니다. 또한 자동으로 코드 스플리팅이 적용되어 각 페이지에 필요한 코드만 로드되므로 성능 최적화에도 도움이 됩니다.

4. "Next.js에서 상태 관리는 어떻게 하나요?"​

Next.js에서의 상태 관리는 애플리케이션의 규모와 요구사항에 따라 다양한 방식으로 구현할 수 있습니다.

가장 기본적인 방법은 React의 내장 훅을 사용한 로컬 상태 관리입니다. useState는 컴포넌트 내부에서 간단한 상태를 관리할 때 사용되며, useReducer는 더 복잡한 상태 로직이 필요한 경우에 활용됩니다. 이러한 로컬 상태 관리는 폼 데이터나 UI 상태와 같이 특정 컴포넌트에 국한된 상태를 다룰 때 적합합니다.

애플리케이션의 규모가 커지고 여러 컴포넌트 간에 상태를 공유해야 하는 경우, 전역 상태 관리 라이브러리를 사용할 수 있습니다. Redux는 예측 가능한 상태 컨테이너로서 복잡한 상태 로직을 체계적으로 관리할 수 있게 해주며, Recoil은 React에 최적화된 상태 관리 라이브러리로 더 간편한 API를 제공합니다. Zustand는 최소한의 보일러플레이트로 직관적인 상태 관리를 가능하게 합니다.

서버 데이터를 다루는 경우, SWR이나 React Query와 같은 데이터 페칭 라이브러리를 사용할 수 있습니다. 이러한 라이브러리들은 서버 상태의 캐싱, 재검증, 낙관적 업데이트 등을 효율적으로 처리할 수 있게 해주며, 실시간 데이터 동기화가 필요한 경우에 특히 유용합니다.

작은 규모의 애플리케이션이나 특정 컴포넌트 트리 내에서만 상태를 공유해야 하는 경우, React의 Context API를 활용할 수 있습니다. Context API는 별도의 라이브러리 설치 없이 React 내장 기능만으로 전역 상태를 관리할 수 있게 해주며, 프로퍼티 드릴링 문제를 해결하는 데 효과적입니다.

5. "Next.js의 성능 최적화 방법들을 설명해주세요."​

Next.js는 웹 애플리케이션의 성능을 최적화하기 위한 다양한 내장 기능을 제공합니다. 이러한 기능들은 개발자가 별도의 복잡한 설정 없이도 최적화된 웹 애플리케이션을 구축할 수 있도록 도와줍니다.

Next.js의 Image Component는 이미지 최적화를 자동으로 처리합니다. 사용자의 디바이스와 뷰포트에 맞춰 이미지 크기를 자동으로 조정하고, WebP와 같은 최신 이미지 포맷을 지원하며, lazy loading을 통해 필요한 시점에만 이미지를 로드합니다. 이를 통해 페이지 로딩 속도를 개선하고 대역폭 사용을 최적화할 수 있습니다.

Script Component는 JavaScript 파일의 로딩을 최적화합니다. 스크립트의 로딩 전략을 'beforeInteractive', 'afterInteractive', 'lazyOnload' 등으로 세밀하게 제어할 수 있어, 페이지의 초기 로딩 성능을 향상시킬 수 있습니다.

자동 코드 스플리팅은 각 페이지에 필요한 JavaScript 코드만을 따로 번들링하여 제공합니다. 이를 통해 초기 페이지 로드 시 불필요한 코드 다운로드를 방지하고, 필요한 코드만 로드함으로써 애플리케이션의 성능을 최적화합니다.

Incremental Static Regeneration(ISR)은 정적 페이지를 필요에 따라 점진적으로 재생성할 수 있게 해줍니다. 이를 통해 서버 부하를 줄이면서도 데이터의 신선도를 유지할 수 있으며, 사용자에게는 항상 빠른 응답 속도를 제공할 수 있습니다.

마지막으로, Edge Runtime을 통해 사용자와 가까운 위치의 서버에서 페이지를 제공할 수 있습니다. 이는 전 세계 사용자에게 일관된 빠른 응답 속도를 제공하며, 특히 동적 콘텐츠를 다루는 경우에 효과적입니다.

이러한 최적화 기능들은 Next.js 애플리케이션의 성능을 자동으로 향상시키며, 개발자는 비즈니스 로직 구현에 더 집중할 수 있게 됩니다.

6. "getStaticProps와 getServerSideProps의 차이점은 무엇인가요?"​

Next.js에서 데이터 페칭을 위한 두 가지 핵심적인 함수인 getStaticProps와 getServerSideProps는 각각 다른 사용 사례와 장단점을 가지고 있습니다.

getStaticProps는 빌드 시점에 데이터를 가져와서 정적 페이지를 생성하는 함수입니다. 이 방식은 한 번 생성된 페이지를 캐시하여 모든 사용자에게 동일한 콘텐츠를 제공하므로, 매우 빠른 페이지 로딩 속도를 제공합니다. 블로그 포스트, 제품 카탈로그, 문서화 페이지와 같이 데이터가 자주 변경되지 않는 페이지에 이상적입니다. 또한 CDN에서 캐시될 수 있어 전 세계 사용자에게 일관된 빠른 속도를 제공할 수 있습니다.

반면 getServerSideProps는 매 사용자 요청마다 서버에서 데이터를 새로 가져와 페이지를 생성합니다. 이는 실시간 데이터나 사용자별 맞춤 콘텐츠가 필요한 경우에 적합합니다. 예를 들어, 사용자 대시보드, 실시간 가격 정보, 개인화된 추천 시스템 등에서 활용될 수 있습니다. 하지만 매 요청마다 서버에서 페이지를 생성해야 하므로, getStaticProps에 비해 상대적으로 응답 속도가 느리고 서버 부하가 높을 수 있다는 특징이 있습니다.

이 두 함수는 개발자가 페이지의 특성과 요구사항에 따라 적절한 데이터 페칭 전략을 선택할 수 있게 해주며, 이를 통해 최적의 사용자 경험을 제공할 수 있습니다.

7. "Next.js에서 API 라우트를 어떻게 구현하나요?"​

Next.js는 백엔드 API를 구현하기 위한 내장 기능으로 API 라우트를 제공합니다. 이는 별도의 백엔드 서버 설정 없이도 풀스택 애플리케이션을 구축할 수 있게 해주는 강력한 기능입니다.

API 라우트의 기본 구현은 pages/api 디렉토리 내에 JavaScript 파일을 생성하는 것으로 시작됩니다. 예를 들어, pages/api/users.js 파일에서는 handler 함수를 export하여 API 엔드포인트를 생성할 수 있습니다. 이 handler 함수는 요청(req)과 응답(res) 객체를 매개변수로 받아 HTTP 요청을 처리합니다.

HTTP 메소드에 따른 다른 동작을 구현하기 위해서는 req.method를 사용하여 요청 메소드를 확인하고 적절한 처리를 할 수 있습니다. 예를 들어, GET 요청에서는 데이터를 조회하고, POST 요청에서는 새로운 데이터를 생성하는 등의 로직을 구현할 수 있습니다.

동적 API 라우트는 pages/api 디렉토리 내에서 대괄호([])를 사용하여 구현할 수 있습니다. 예를 들어, pages/api/users/[id].js 파일을 생성하면 '/api/users/1'과 같은 동적 경로를 처리할 수 있으며, req.query를 통해 동적 파라미터에 접근할 수 있습니다.

또한, Next.js는 API 라우트에 미들웨어를 적용할 수 있는 기능을 제공합니다. 이를 통해 인증, 로깅, 에러 처리 등의 공통 기능을 여러 API 라우트에 걸쳐 재사용할 수 있습니다. 미들웨어는 요청이 처리되기 전에 실행되어 요청을 수정하거나 응답을 조작할 수 있으며, 이는 코드의 재사용성과 유지보수성을 높여줍니다.

8. Next.js의 SSR, CSR, SSG의 차이점을 설명해주시고, 각각 어떤 상황에서 사용하는 것이 적합한지 설명해주세요.​

Next.js는 웹 애플리케이션 개발에 있어 세 가지 주요 렌더링 방식인 SSR, CSR, SSG를 유연하게 지원합니다. 각 방식은 고유한 특징과 적용 사례를 가지고 있어, 개발자는 애플리케이션의 요구사항에 따라 적절한 방식을 선택할 수 있습니다.

서버 사이드 렌더링(SSR)은 서버에서 페이지를 완전히 렌더링한 후 클라이언트에게 전달하는 방식입니다. 이는 검색엔진 최적화가 중요한 페이지나 초기 로딩 속도가 중요한 경우에 특히 유용합니다. 전자상거래 사이트의 상품 상세 페이지나 실시간 뉴스 사이트와 같이 SEO와 빠른 초기 로딩이 중요한 경우에 적합합니다. 다만, 서버 자원을 많이 사용하고 페이지 전환 시 전체 페이지를 다시 로드해야 하는 단점이 있습니다.

클라이언트 사이드 렌더링(CSR)은 브라우저에서 JavaScript를 통해 페이지를 렌더링하는 방식으로, 서버는 최소한의 HTML과 JavaScript 파일만 전송합니다. 관리자 대시보드나 실시간 채팅 애플리케이션과 같이 풍부한 사용자 인터랙션이 필요한 경우에 적합합니다. CSR은 서버 부하가 적고 페이지 전환이 빠르다는 장점이 있지만, 초기 로딩 시간이 길고 SEO가 어렵다는 단점이 있습니다.

정적 사이트 생성(SSG)은 빌드 시점에 페이지를 미리 생성하여 정적 파일로 제공하는 방식입니다. 회사 소개 페이지, 기술 문서, 블로그 포스트와 같이 콘텐츠가 자주 변경되지 않는 경우에 이상적입니다. SSG는 매우 빠른 페이지 로딩 속도와 높은 보안성을 제공하지만, 동적 콘텐츠 처리가 어렵고 빌드 시간이 길어질 수 있다는 제한사항이 있습니다.

실제 애플리케이션 개발에서는 이러한 렌더링 방식들을 페이지의 특성과 요구사항에 맞게 혼합하여 사용하는 것이 일반적입니다. 예를 들어, 마케팅 페이지는 SSG로, 제품 상세 페이지는 SSR로, 사용자 대시보드는 CSR로 구현하는 방식으로 각 페이지의 특성에 맞는 최적의 렌더링 전략을 선택할 수 있습니다. Next.js는 이러한 하이브리드 접근 방식을 쉽게 구현할 수 있도록 지원하여, 개발자가 애플리케이션의 각 부분에 가장 적합한 렌더링 방식을 선택할 수 있게 해줍니다.

9. Next.js에서 SEO 최적화를 위해 어떤 방법들을 사용해보셨나요?​

Next.js에서의 SEO 최적화는 여러 가지 핵심적인 기능과 방법을 통해 구현할 수 있습니다. 이러한 최적화는 검색엔진에서의 가시성을 높이고 사용자 경험을 개선하는 데 중요한 역할을 합니다.

먼저, Next.js 13.2 버전부터 도입된 Metadata API는 정적 및 동적 메타데이터를 효과적으로 관리할 수 있게 해줍니다. 이 API를 통해 기본적인 title, description 태그부터 OpenGraph, Twitter 카드까지 다양한 메타데이터를 설정할 수 있습니다. 특히 generateMetadata 함수를 사용하면 동적 라우트에서도 각 페이지에 최적화된 메타데이터를 생성할 수 있으며, 메타데이터 템플릿을 통해 일관된 형식을 유지하면서도 페이지별로 특화된 정보를 제공할 수 있습니다.

구조화된 데이터 마크업은 검색 엔진이 콘텐츠를 더 정확하게 이해할 수 있도록 도와줍니다. schema.org 형식의 JSON-LD를 구현하여 블로그 포스트, 제품 정보, FAQ 등 다양한 유형의 콘텐츠에 대한 리치 스니펫을 검색 결과에 표시할 수 있습니다. 이는 클릭률 향상에 직접적인 도움이 됩니다.

sitemap.xml과 robots.txt의 동적 생성도 중요한 SEO 요소입니다. Next.js의 app 디렉토리에서는 데이터베이스의 모든 URL을 자동으로 사이트맵에 포함시킬 수 있으며, 각 URL의 중요도와 업데이트 빈도도 설정할 수 있습니다. robots.txt를 통해 검색 엔진 크롤러의 접근을 제어하고 사이트맵의 위치를 알려줄 수 있습니다.

서버 사이드 렌더링과 성능 최적화는 SEO에 직접적인 영향을 미칩니다. Next.js의 서버 사이드 렌더링을 통해 검색 엔진이 JavaScript 실행 없이도 콘텐츠를 크롤링할 수 있으며, Next/Image 컴포넌트를 사용한 이미지 최적화, 폰트 최적화, 코드 분할 등을 통해 페이지 로딩 속도를 개선할 수 있습니다.

마지막으로, 웹 접근성과 시맨틱 마크업의 적절한 사용은 검색 엔진이 콘텐츠의 구조와 의미를 이해하는 데 도움을 주며, 이는 더 나은 SEO 결과로 이어집니다. 시맨틱 HTML과 ARIA 레이블, 역할을 적절히 설정하여 웹 접근성을 개선하는 것이 중요합니다.

이러한 SEO 최적화 방법들을 종합적으로 적용함으로써, Next.js 애플리케이션의 검색 엔진 가시성을 높이고 사용자 경험을 개선할 수 있습니다. Next.js의 내장 기능들을 활용하면 개발자가 직접 구현해야 하는 부분을 최소화하면서도 효과적인 SEO 최적화를 달성할 수 있습니다.

10. 왜 SSR를 할 경우 SEO에 직접적인 영향을 주나요?​

Next.js의 서버 사이드 렌더링(SSR)과 성능 최적화가 작동하는 원리를 설명해드리겠습니다:

서버 사이드 렌더링의 작동 원리:

  1. 사용자나 검색엔진이 페이지를 요청하면, Next.js 서버는 React 컴포넌트를 서버에서 먼저 실행합니다.
  2. 이 과정에서 필요한 데이터를 가져오고, React 컴포넌트를 HTML로 변환합니다.
  3. 생성된 HTML을 클라이언트에 전송합니다.
  4. 클라이언트는 이미 완성된 HTML을 받기 때문에, JavaScript가 로드되기 전에도 콘텐츠를 볼 수 있습니다.
  5. 이후 JavaScript가 로드되면 hydration 과정을 통해 정적 HTML을 동적 React 애플리케이션으로 전환합니다.

이러한 과정이 SEO에 도움이 되는 이유:

  1. 검색엔진이 JavaScript 실행 없이도 완성된 HTML을 크롤링할 수 있음
  2. 페이지 로딩 속도가 빨라져 Core Web Vitals 점수 향상
  3. 모바일 기기에서도 최적화된 성능으로 모바일 검색 순위 개선
  4. 사용자 경험이 개선되어 이탈률 감소, 체류 시간 증가

11. Next.js의 라우팅 시스템에 대해 설명해주세요.​

Next.js의 라우팅 시스템은 파일 시스템을 기반으로 하는 직관적이고 강력한 구조를 제공합니다. 특히 최신 버전의 app 디렉토리를 사용하는 App Router는 React의 최신 기능들을 최대한 활용할 수 있게 해줍니다.

기본적인 라우팅 구조는 디렉토리 구조를 그대로 URL 경로로 변환합니다. app 디렉토리 내부에 생성된 폴더는 자동으로 라우트가 되며, 각 폴더 내의 page.tsx 파일이 해당 라우트의 UI를 담당합니다. 예를 들어 'app/about/page.tsx'를 생성하면 '/about' 경로로 자동으로 접근할 수 있게 됩니다.

Dynamic Routes는 동적인 데이터나 매개변수를 기반으로 페이지를 생성하는 강력한 기능입니다. 대괄호([])를 사용하여 구현하며, 다양한 패턴을 지원합니다. 단일 매개변수를 처리하는 [id], 여러 매개변수를 처리하는 [category]/[id], 그리고 여러 경로를 한 번에 처리하는 [...slug]와 같은 Catch-all 라우팅 등을 구현할 수 있습니다. 이를 통해 블로그 포스트, 제품 상세 페이지 등 동적인 콘텐츠를 효과적으로 처리할 수 있습니다.

Parallel Routes는 '@' 기호를 사용하여 같은 레이아웃 내에서 여러 페이지를 동시에 렌더링할 수 있게 해주는 혁신적인 기능입니다. 이는 메인 콘텐츠를 보면서 동시에 모달이나 사이드바와 같은 독립적인 콘텐츠를 표시해야 할 때 특히 유용합니다. 각 병렬 라우트는 독립적인 로딩 상태와 에러 처리를 가질 수 있어, 복잡한 UI 패턴을 깔끔하게 구현할 수 있습니다.

더욱 강력한 점은 Dynamic Routes와 Parallel Routes를 조합하여 사용할 수 있다는 것입니다. 예를 들어, 특정 게시물을 보면서 동시에 관련 댓글을 모달로 표시하거나, 사용자 프로필을 보면서 동시에 활동 내역을 사이드바에 표시하는 등의 복잡한 UI 패턴을 효과적으로 구현할 수 있습니다. 이러한 유연한 라우팅 시스템은 현대적인 웹 애플리케이션에서 요구되는 다양한 사용자 경험을 구현하는 데 큰 도움이 됩니다.